package com.example.app.ui.health.User;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 心率和血氧可视化图表
 * 支持实时数据绘制和平滑动画
 * 医疗级别的可视化效果
 */
public class HeartRateChartView extends View {
    private Paint hrPaint, spo2Paint, axisPaint, textPaint, gridPaint, shadowPaint, borderPaint;
    private Paint hrWavePaint; // 医疗级心电图波形画笔
    private Path hrPath, spo2Path, hrShadowPath, hrWavePath;
    
    // 数据存储 - 心率、血氧和时间戳
    private List<DataPoint> dataPoints = new LinkedList<>();
    private float animationProgress = 1.0f;
    private int[] smoothedHR; // 平滑后的心率数据
    private float[] smoothedSpO2; // 平滑后的血氧数据
    
    // 同步数据处理
    private long startTime = 0;
    private int lastHeartRate = 0;
    private float lastSpO2 = 0;
    
    // 心电图波形参数
    private float[] wavePattern = {
        0.0f, 0.1f, 0.2f, 0.1f, 0.0f, 0.0f, 0.0f, -0.1f, 0.8f, 0.4f, -0.2f, -0.1f, 0.0f, 0.0f
    }; // P-QRS-T波形模板
    private int waveSampleIndex = 0;
    
    // 图表常量配置
    private static final int MAX_POINTS = 100; // 存储点数
    private static final long DATA_WINDOW_MS = 10000; // 显示10秒数据
    private static final int HR_MIN = 40;     // 心率最小值
    private static final int HR_MAX = 200;    // 心率最大值
    private static final float SPO2_MIN = 85; // 血氧最小值 (医疗设备通常从85%开始)
    private static final float SPO2_MAX = 100;// 血氧最大值
    private static final int PADDING = 50;    // 图表内边距
    private static final int SMOOTH_FACTOR = 5; // 曲线平滑系数
    
    // 颜色配置 - 医疗设备标准配色
    private static final String HR_COLOR = "#00FF00";   // 心率线颜色 - 医疗绿
    private static final String SPO2_COLOR = "#00A8F3"; // 血氧线颜色 - 医疗蓝
    private static final String BG_COLOR = "#000000";   // 背景色 - 黑色
    private static final String GRID_COLOR = "#323232"; // 网格线颜色
    private static final String BORDER_COLOR = "#4D4D4D"; // 边框颜色
    
    // 内部数据点类，存储同步的心率和血氧数据
    private static class DataPoint {
        long timestamp;
        int heartRate;
        float spO2;
        
        DataPoint(long timestamp, int heartRate, float spO2) {
            this.timestamp = timestamp;
            this.heartRate = heartRate;
            this.spO2 = spO2;
        }
    }

    public HeartRateChartView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaints();
        initPaths();
        startTime = System.currentTimeMillis();
    }

    /**
     * 初始化所有画笔
     */
    private void initPaints() {
        // 心率线画笔
        hrPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        hrPaint.setColor(Color.parseColor(HR_COLOR));
        hrPaint.setStrokeWidth(2f);
        hrPaint.setStyle(Paint.Style.STROKE);
        hrPaint.setStrokeJoin(Paint.Join.ROUND);
        hrPaint.setStrokeCap(Paint.Cap.ROUND);
        
        // 心电图波形画笔
        hrWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        hrWavePaint.setColor(Color.parseColor(HR_COLOR));
        hrWavePaint.setStrokeWidth(2f);
        hrWavePaint.setStyle(Paint.Style.STROKE);
        hrWavePaint.setStrokeJoin(Paint.Join.ROUND);
        
        // 血氧线画笔
        spo2Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        spo2Paint.setColor(Color.parseColor(SPO2_COLOR));
        spo2Paint.setStrokeWidth(2f);
        spo2Paint.setStyle(Paint.Style.STROKE);
        spo2Paint.setStrokeJoin(Paint.Join.ROUND);
        spo2Paint.setStrokeCap(Paint.Cap.ROUND);
        
        // 坐标轴画笔
        axisPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        axisPaint.setColor(Color.WHITE);
        axisPaint.setStrokeWidth(1.5f);
        
        // 文本画笔
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(24f);
        textPaint.setTextAlign(Paint.Align.LEFT);
        
        // 网格线画笔
        gridPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        gridPaint.setColor(Color.parseColor(GRID_COLOR));
        gridPaint.setStrokeWidth(0.8f);
        gridPaint.setPathEffect(new DashPathEffect(new float[] {4, 4}, 0));
        
        // 阴影画笔 - 半透明效果
        shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        shadowPaint.setColor(Color.parseColor(HR_COLOR));
        shadowPaint.setAlpha(20); // 降低透明度，更符合医疗设备的视觉效果
        shadowPaint.setStyle(Paint.Style.FILL);
        
        // 边框画笔
        borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        borderPaint.setColor(Color.parseColor(BORDER_COLOR));
        borderPaint.setStrokeWidth(2f);
        borderPaint.setStyle(Paint.Style.STROKE);
    }
    
    /**
     * 初始化路径对象
     */
    private void initPaths() {
        hrPath = new Path();
        spo2Path = new Path();
        hrShadowPath = new Path();
        hrWavePath = new Path();
    }

    /**
     * 添加新的心率和血氧数据，保证同步
     * @param heartRate 心率值
     * @param spO2 血氧值
     */
    public void addSynchronizedData(int heartRate, float spO2) {
        lastHeartRate = heartRate;
        lastSpO2 = spO2;
        
        // 记录同步的数据点
        long currentTime = System.currentTimeMillis();
        DataPoint newPoint = new DataPoint(currentTime, heartRate, spO2);
        dataPoints.add(newPoint);
        
        // 移除超出显示时间窗口的数据点
        long cutoffTime = currentTime - DATA_WINDOW_MS;
        while (!dataPoints.isEmpty() && dataPoints.get(0).timestamp < cutoffTime) {
            dataPoints.remove(0);
        }
        
        // 最多保留MAX_POINTS个点
        while (dataPoints.size() > MAX_POINTS) {
            dataPoints.remove(0);
        }
        
        // 记录日志
        Log.d("HeartRateChartView", "添加同步数据 - 心率: " + heartRate + ", 血氧: " + spO2);
        
        // 触发动画
        animateDataAddition();
    }
    
    /**
     * 添加新的心率数据（向后兼容）
     */
    public void addHeartRate(int rate) {
        // 保持心率数据与上次的血氧同步
        addSynchronizedData(rate, lastSpO2);
    }
    
    /**
     * 添加新的血氧数据（向后兼容）
     */
    public void addSpO2(float value) {
        // 保持血氧数据与上次的心率同步
        addSynchronizedData(lastHeartRate, value);
    }
    
    /**
     * 数据添加动画效果
     */
    private void animateDataAddition() {
        animationProgress = 0f;
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
        animator.setDuration(300);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(animation -> {
            animationProgress = (float) animation.getAnimatedValue();
            invalidate();
        });
        animator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawBorder(canvas);
        drawGrid(canvas);
        drawAxes(canvas);
        drawSynchronizedData(canvas);
        drawLegends(canvas);
    }

    /**
     * 绘制图表背景
     */
    private void drawBackground(Canvas canvas) {
        canvas.drawColor(Color.parseColor(BG_COLOR));
    }
    
    /**
     * 绘制图表边框 - 医疗设备常有边框
     */
    private void drawBorder(Canvas canvas) {
        RectF border = new RectF(PADDING/2, PADDING/2, getWidth() - PADDING/2, getHeight() - PADDING/2);
        canvas.drawRoundRect(border, 8, 8, borderPaint);
    }

    /**
     * 绘制坐标轴和刻度
     */
    private void drawAxes(Canvas canvas) {
        // 左侧Y轴 (心率)
        canvas.drawLine(PADDING, PADDING, PADDING, getHeight() - PADDING, axisPaint);
        // 右侧Y轴 (血氧)
        canvas.drawLine(getWidth() - PADDING, PADDING, getWidth() - PADDING, getHeight() - PADDING, axisPaint);
        // X轴
        canvas.drawLine(PADDING, getHeight() - PADDING, getWidth() - PADDING, getHeight() - PADDING, axisPaint);
        
        // 心率刻度
        for (int value = HR_MIN; value <= HR_MAX; value += 40) {
            float y = map(value, HR_MIN, HR_MAX, getHeight() - PADDING, PADDING);
            canvas.drawText(String.valueOf(value), PADDING - 45, y + 8, textPaint);
            canvas.drawLine(PADDING - 5, y, PADDING, y, axisPaint);
        }
        
        // 血氧刻度
        for (float value = SPO2_MIN; value <= SPO2_MAX; value += 5) {
            float y = map(value, SPO2_MIN, SPO2_MAX, getHeight() - PADDING, PADDING);
            String label = String.format("%.0f%%", value);
            canvas.drawText(label, getWidth() - PADDING + 10, y + 8, textPaint);
            canvas.drawLine(getWidth() - PADDING, y, getWidth() - PADDING + 5, y, axisPaint);
        }
        
        // 时间刻度 (X轴)
        int timeSteps = 5; // 5个时间标记
        for (int i = 0; i <= timeSteps; i++) {
            float x = PADDING + (getWidth() - 2 * PADDING) * i / timeSteps;
            float seconds = (DATA_WINDOW_MS / 1000f) * i / timeSteps;
            String timeLabel = String.format("%.0fs", seconds);
            canvas.drawText(timeLabel, x - 15, getHeight() - PADDING + 25, textPaint);
        }
    }

    /**
     * 绘制网格线
     */
    private void drawGrid(Canvas canvas) {
        // 水平网格线 - 心率刻度线
        for (int value = HR_MIN; value <= HR_MAX; value += 20) {
            float y = map(value, HR_MIN, HR_MAX, getHeight() - PADDING, PADDING);
            canvas.drawLine(PADDING, y, getWidth() - PADDING, y, gridPaint);
        }
        
        // 垂直网格线 - 时间线
        int gridColumns = 10;
        for (int i = 0; i <= gridColumns; i++) {
            float x = PADDING + (getWidth() - 2 * PADDING) * i / gridColumns;
            canvas.drawLine(x, PADDING, x, getHeight() - PADDING, gridPaint);
        }
    }

    /**
     * 绘制同步的心率和血氧数据
     */
    private void drawSynchronizedData(Canvas canvas) {
        if (dataPoints.isEmpty()) {
            return;
        }
        
        // 清除路径
        hrPath.reset();
        spo2Path.reset();
        hrShadowPath.reset();
        hrWavePath.reset();
        
        // 获取当前时间和最早时间点
        long currentTime = dataPoints.get(dataPoints.size() - 1).timestamp;
        long startTimestamp = currentTime - DATA_WINDOW_MS;
        
        // 绘制医疗级心电图波形
        drawECGWaveform(canvas, startTimestamp, currentTime);
        
        // 计算时间到X坐标的映射函数
        float xWidth = getWidth() - 2 * PADDING;
        
        // 绘制心率和血氧曲线
        boolean firstPoint = true;
        for (int i = 0; i < dataPoints.size(); i++) {
            DataPoint point = dataPoints.get(i);
            
            // 计算X坐标 (基于时间)
            float x = PADDING + xWidth * (point.timestamp - startTimestamp) / DATA_WINDOW_MS;
            
            // 计算心率的Y坐标
            float hrY = map(point.heartRate, HR_MIN, HR_MAX, getHeight() - PADDING, PADDING);
            
            // 计算血氧的Y坐标
            float spo2Y = map(point.spO2, SPO2_MIN, SPO2_MAX, getHeight() - PADDING, PADDING);
            
            // 第一个点
            if (firstPoint) {
                hrPath.moveTo(x, hrY);
                hrShadowPath.moveTo(x, hrY);
                spo2Path.moveTo(x, spo2Y);
                firstPoint = false;
            } 
            // 中间点
            else if (i < dataPoints.size() - 1) {
                // 使用贝塞尔曲线连接点，使曲线更平滑
                float nextX = PADDING + xWidth * (dataPoints.get(i+1).timestamp - startTimestamp) / DATA_WINDOW_MS;
                float nextHrY = map(dataPoints.get(i+1).heartRate, HR_MIN, HR_MAX, getHeight() - PADDING, PADDING);
                float nextSpo2Y = map(dataPoints.get(i+1).spO2, SPO2_MIN, SPO2_MAX, getHeight() - PADDING, PADDING);
                
                // 控制点
                float cpx1 = x + (nextX - x) / 3;
                float cpx2 = x + 2 * (nextX - x) / 3;
                
                // 心率曲线
                hrPath.cubicTo(cpx1, hrY, cpx2, nextHrY, nextX, nextHrY);
                hrShadowPath.cubicTo(cpx1, hrY, cpx2, nextHrY, nextX, nextHrY);
                
                // 血氧曲线
                spo2Path.cubicTo(cpx1, spo2Y, cpx2, nextSpo2Y, nextX, nextSpo2Y);
            }
            // 最后一个点 (应用动画)
            else {
                hrPath.lineTo(x, hrY);
                hrShadowPath.lineTo(x, hrY);
                spo2Path.lineTo(x, spo2Y);
            }
        }
        
        // 完成阴影路径
        DataPoint lastPoint = dataPoints.get(dataPoints.size() - 1);
        float lastX = PADDING + xWidth * (lastPoint.timestamp - startTimestamp) / DATA_WINDOW_MS;
        hrShadowPath.lineTo(lastX, getHeight() - PADDING);
        hrShadowPath.lineTo(PADDING, getHeight() - PADDING);
        hrShadowPath.close();
        
        // 绘制阴影
        canvas.drawPath(hrShadowPath, shadowPaint);
        
        // 绘制心率曲线
        canvas.drawPath(hrPath, hrPaint);
        
        // 绘制血氧曲线
        canvas.drawPath(spo2Path, spo2Paint);
    }
    
    /**
     * 绘制医疗级心电图波形
     */
    private void drawECGWaveform(Canvas canvas, long startTimestamp, long currentTime) {
        // 只在有足够心率数据时绘制心电图波形
        if (dataPoints.size() < 2 || lastHeartRate < 40) {
            return;
        }
        
        // 计算心跳间隔 (毫秒)
        float beatInterval = 60000f / lastHeartRate;
        
        // 计算波形参数
        float xWidth = getWidth() - 2 * PADDING;
        float waveHeight = (getHeight() - 2 * PADDING) * 0.15f; // 波形高度为图表高度的15%
        float waveY = getHeight() - PADDING - (getHeight() - 2 * PADDING) * 0.2f; // 波形位置
        
        // 生成心电图波形
        hrWavePath.reset();
        
        // 计算每个心跳周期的宽度 (像素)
        float beatWidth = xWidth * beatInterval / DATA_WINDOW_MS;
        
        // 确定要绘制的完整心跳周期数量
        int numCycles = (int)Math.ceil(DATA_WINDOW_MS / beatInterval) + 1;
        
        // 第一个心跳的起始位置
        float startX = PADDING + xWidth - (currentTime - startTimestamp) % (long)beatInterval * xWidth / DATA_WINDOW_MS;
        
        // 绘制连续的心电图波形
        for (int cycle = 0; cycle < numCycles; cycle++) {
            float cycleStartX = startX - cycle * beatWidth;
            
            // 如果该心跳周期已经超出可见区域，则跳过
            if (cycleStartX + beatWidth < PADDING) continue;
            
            // 波形起点
            hrWavePath.moveTo(cycleStartX, waveY);
            
            // 绘制一个完整的心电图波形
            for (int i = 0; i < wavePattern.length; i++) {
                float x = cycleStartX + i * beatWidth / wavePattern.length;
                float y = waveY - wavePattern[i] * waveHeight;
                
                // 确保不超出图表范围
                if (x >= PADDING) {
                    if (i == 0) {
                        hrWavePath.moveTo(x, y);
                    } else {
                        hrWavePath.lineTo(x, y);
                    }
                }
            }
        }
        
        // 绘制心电图波形
        canvas.drawPath(hrWavePath, hrWavePaint);
    }

    /**
     * 将值映射到图表坐标系
     */
    private float map(float value, float inMin, float inMax, float outMin, float outMax) {
        return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
    }
    
    /**
     * 绘制图例说明
     */
    private void drawLegends(Canvas canvas) {
        float startX = PADDING + 20;
        float startY = PADDING / 2 - 10;
        
        // 心率图例
        canvas.drawLine(startX, startY, startX + 30, startY, hrPaint);
        canvas.drawText("心率(BPM)", startX + 40, startY + 8, textPaint);
        
        // 血氧图例
        float spo2X = startX + 180;
        canvas.drawLine(spo2X, startY, spo2X + 30, startY, spo2Paint);
        canvas.drawText("血氧(%)", spo2X + 40, startY + 8, textPaint);
    }
    
    /**
     * 清除所有数据
     */
    public void clearData() {
        Log.d("HeartRateChartView", "清除所有数据");
        dataPoints.clear();
        lastHeartRate = 0;
        lastSpO2 = 0;
        invalidate();
    }
    
    /**
     * 检查图表状态并打印调试信息
     */
    public void debugStatus() {
        Log.d("HeartRateChartView", "---------------- 图表状态 ----------------");
        Log.d("HeartRateChartView", "数据点数: " + dataPoints.size());
        Log.d("HeartRateChartView", "最后心率值: " + lastHeartRate);
        Log.d("HeartRateChartView", "最后血氧值: " + lastSpO2);
        Log.d("HeartRateChartView", "------------------------------------------");
    }
    
    /**
     * 手动触发刷新图表
     */
    public void refreshChart() {
        invalidate();
        Log.d("HeartRateChartView", "手动刷新图表完成");
    }
}